/**
 * @author Ahammer
 * @date    2009
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package main;

import java.awt.image.DataBuffer;
import java.awt.image.ImagingOpException;
import java.awt.image.IndexColorModel;

import java.awt.image.renderable.ParameterBlock;

import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;



public class Look {

	public static final long serialVersionUID = 1L;
	private static LookFrame       lookJFrame = null;
	private static LookFrame  extraLookJFrame = null;  

    //public static TiledImage  tileImage = null;;
       
 	/**
	 * This method initializes Look
	 */
	
	public Look(){
	
	}

	/**
	 * This static method creates and shows the GUI
	*/
	public static void createAndShowGUI() {
		lookJFrame = new LookFrame();
		lookJFrame.createAndShowGUI();
		lookJFrame.lookJFrame.setTitle("Look");
		IqmTools.setLookDisplayJAI(lookJFrame.getLookDisplayJAI());
	}
	/**
	 * This method destroys the current GUI
	*/
	public static void destroyGUI() throws Exception{
		lookJFrame.destroyGUI();
		//lookJFrame.dispose();
		//lookJFrame = null;
	}
	
	/**
	 * This method creates an Extra Look
	 */
	public static void createExtraLook() {
		lookJFrame  = new LookFrame();
		lookJFrame.createAndShowGUI();
		String frameTitle = "ExtraLook";
		lookJFrame.lookJFrame.setTitle(frameTitle);
		int index = IqmTools.getCurrManagerImgIndex();
		PlanarImage pi = Tank.getCurrentTankImageAt(index);
		Look.setNewImage(pi);
		try {
			lookJFrame.lookJFrame.setTitle(frameTitle+"      "+ (lookJFrame.origImage.getProperty("image_name")).toString());
		} catch (NullPointerException e) {
			lookJFrame.lookJFrame.setTitle(frameTitle);
		}	
		IqmTools.setLookDisplayJAI(lookJFrame.getLookDisplayJAI()); //???
	}

	/**
	 * This method gets the current Look image
	 */
	public static PlanarImage getCurrImg(){
		return lookJFrame.origImage;
	}
	/**
	 * This method adds a new image to DisplayJAI
	 * @param PlanarImage pi
	 */
	public static void setNewImage (PlanarImage pi) {
		
		if (pi == null){
			Board.appendTexln("Look: There is not a valid image to display");
			return;
		}
		if (lookJFrame == null) {
			Look.createAndShowGUI();
			lookJFrame.zoom = 1.0F;
		} 
		lookJFrame.origImage = pi;
		String frameTitle = lookJFrame.lookJFrame.getTitle();
		if (frameTitle.contains("ExtraLook")){
			frameTitle = "ExtraLook";
		}else{
			frameTitle = "Look";
		}
		try {
			lookJFrame.lookJFrame.setTitle(frameTitle+"      "+ (lookJFrame.origImage.getProperty("image_name")).toString());
		} catch (NullPointerException e) {
			lookJFrame.lookJFrame.setTitle(frameTitle);
		}
		// Create the StringBuffer instance for the pixel information.
		lookJFrame.pixelInfo = new StringBuffer(50);
	     
	    // Get some data about the image
		lookJFrame.width  = lookJFrame.origImage.getWidth();
		lookJFrame.height = lookJFrame.origImage.getHeight();
		
 		int dataType = lookJFrame.origImage.getSampleModel().getDataType(); // gets the data type
    
	    switch(dataType){
	      case DataBuffer.TYPE_BYTE: 	lookJFrame.imgType = "BYTE";   break;
	      case DataBuffer.TYPE_SHORT:   lookJFrame.imgType = "SHORT";  break;
	      case DataBuffer.TYPE_USHORT:	lookJFrame.imgType = "USHORT"; break;
	      case DataBuffer.TYPE_INT:     lookJFrame.imgType = "INT";    break; 	
	      case DataBuffer.TYPE_FLOAT:	lookJFrame.imgType = "FLOAT";  break;
	      case DataBuffer.TYPE_DOUBLE:  lookJFrame.imgType = "DOUBLE"; break;
	    }

	    int numBands = lookJFrame.origImage.getNumBands();
	    if (lookJFrame.imgType.equals("DOUBLE")) lookJFrame.doublePixelValue = new double[numBands];
	    if (lookJFrame.imgType.equals("FLOAT"))  lookJFrame.floatPixelValue  = new float [numBands];
	    if (lookJFrame.imgType.equals("BYTE") || lookJFrame.imgType.equals("SHORT") || lookJFrame.imgType.equals("USHORT")|| lookJFrame.imgType.equals("INT"))  {
	    	lookJFrame.intPixelValue  = new int [numBands];
	    }
	    
	    lookJFrame.isIndexed = (lookJFrame.origImage.getColorModel() instanceof IndexColorModel);
	    if (lookJFrame.isIndexed){
	      IndexColorModel icm = (IndexColorModel)lookJFrame.origImage.getColorModel();
	      int mapSize = icm.getMapSize();
	      byte[][] lut = new byte[3][mapSize];
	      icm.getReds  (lut[0]);
	      icm.getGreens(lut[1]);
	      icm.getBlues (lut[2]);
	      lookJFrame.lut = new short[3][mapSize]; //short: no negative values
	      for(int i=0;i<mapSize;i++){
	    	  lookJFrame.lut[0][i] = lut[0][i] >= 0 ? lut[0][i] : (short)(lut[0][i]+256);
	          lookJFrame.lut[1][i] = lut[1][i] >= 0 ? lut[1][i] : (short)(lut[1][i]+256);
	          lookJFrame.lut[2][i] = lut[2][i] >= 0 ? lut[2][i] : (short)(lut[2][i]+256);
	      }
	    } // end if indexed
	
	    //set the pixel iterator
	    // //if (!(lookJFrame.readIterator == null)) lookJFrame.readIterator.done();
	    //lookJFrame.readIterator = RandomIterFactory.create(lookJFrame.origImage, null); // creates the iterator.
	    // //readIterator = RandomIterFactory.create(origImage, new Rectangle(0,0,width, height)); // creates the iterator.
	
	    lookJFrame.rendImage = zoomImage(lookJFrame.origImage);  
	    updateLookDisplayJAI();
	}
	
	private void setNewInfo() {
		// TODO Auto-generated method stub	
	}
	/**
	 * This method zooms the image
	 */
	public static PlanarImage zoomImage(PlanarImage pi){
		lookJFrame.zoomPB = new ParameterBlockJAI("scale");
		lookJFrame.zoomPB.addSource(pi);
		lookJFrame.zoomPB.setParameter("xScale", lookJFrame.zoom);
		lookJFrame.zoomPB.setParameter("yScale", lookJFrame.zoom);
		lookJFrame.zoomPB.setParameter("xTrans", 0.0F);
		lookJFrame.zoomPB.setParameter("yTrans", 0.0F);
		lookJFrame.zoomPB.setParameter("interpolation", new InterpolationNearest());  //just resample
		pi = JAI.create("scale", lookJFrame.zoomPB);
	
		if (pi == null) {
			throw new ImagingOpException("Unable to scale");
		}
		return pi;
	}
	/**
	 * This method updates LookDisplayJAI
	 */
	public static void updateLookDisplayJAI(){    
		lookJFrame.getLookDisplayJAI().set(lookJFrame.rendImage);	      
		////readIterator = RandomIterFactory.create(rendImage, null); // recreates the iterator for the proper image	     		  
		//lookJFrame.lookDisplayJAI.revalidate(); until 2009 12 27
		//lookJFrame.lookDisplayJAI.repaint();    until 2009 12 27
		////lookJFrame.repaint();		 	      
		//lookJFrame.getJFrame().toFront();        until 2009 12 27
		
		//pixelInfo.setLength(0); // clear the StringBuffer     
	    String zom = "Zoom: " + lookJFrame.zoom;
		String siz = "       X "+ lookJFrame.width+"  Y "+ lookJFrame.height+"   ";
		//System.out.println("Look: zom + siz: " + zom +siz);
		lookJFrame.pixelInfo.append(zom + siz);
		lookJFrame.lookJLabel.setText(lookJFrame.pixelInfo.toString());  
		lookJFrame.getJFrame().toFront();
	}
	
	/**
	 * This method resets the Look window
	 */
	public static void reset() {
		if (lookJFrame != null){
			//System.out.println("Look.reset: I'm here");
			//PlanarImage pi =  JAI.create("url", ClassLoader.getSystemResource("imgs/LogoIqm_v1.0_800x600_Bright.png"));
			PlanarImage pi =  JAI.create("url", ClassLoader.getSystemResource("imgs/LogoIqm_v1.0_800x600_LightGrey.png"));
			//pi.setProperty("file_name", "imgs/LogoIqm_v1.0_800x600_Bright.png");	
			pi.setProperty("file_name", "imgs/LogoIqm_v1.0_800x600_LightGrey.png");	
			pi.setProperty("image_name", " ");	
			float zoomX = ((float)lookJFrame.getJFrame().getWidth()-15)/((float)pi.getWidth());
			float zoomY = ((float)lookJFrame.getJFrame().getHeight()-50)/((float)pi.getHeight());
			ParameterBlock pb = new ParameterBlock();
			pb.addSource(pi);
			pb.add(zoomX);//x scale factor
			pb.add(zoomY);//y scale factor
			pb.add(0.0F);//x translate
			pb.add(0.0F);//y translate
			pb.add(new InterpolationNearest());//interpolation method
			pi = JAI.create("scale", pb);
			//lookJFrame.zoom = (float) 1;
			Look.setNewImage(pi);
		}
	}

	/**
	 * This method gets the current LookFrame
	 * @return lookJFrame
	 */
	public static LookFrame getLookFrame() {
		return lookJFrame;
	}

	/**
	 * This method sets the current LookJFrame
	 * @param object
	 */
	public static void setLookFrame(LookFrame lf) {
		lookJFrame = lf;		
	}
} //End of Look
